package com.monitor.module.user.controller;

import com.monitor.entity.pojo.user.User;
import com.monitor.entity.request.user.UserCompanyRequest;
import com.monitor.entity.request.user.UserRequest;
import com.monitor.entity.response.ResultCode;
import com.monitor.entity.response.Rs;
import com.monitor.module.user.service.UserService;
import com.monitor.utils.PoJoUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

/**
 * 用户接口.
 *
 * @author Li Zhiyuan
 * @since 2020-11-10
 */
@RestController
@RequestMapping("/user")
@Slf4j
@Api(tags = "用户接口")
public class UserController {
    @Autowired
    private UserService service;

    @Resource
    private RedisTemplate<String, User> redisTemplate;

    /**
     * 用户登录接口
     */
    @PostMapping("/login")
    @ApiOperation(value = "登录", notes = "根据用户账号和密码登录，返回token")
    public ResponseEntity<Rs<Object>> login(@ApiParam("用户账号") @RequestParam("userName") String userName,
                                            @ApiParam("用户密码") @RequestParam("passWord") String passWord, HttpServletRequest request) {
        //根据用户名和密码创建token
        UsernamePasswordToken token = new UsernamePasswordToken(userName, passWord);
        //获取subject认证主体
        Subject subject = SecurityUtils.getSubject();
        try {
            //开始认证，这一步会跳到我们自定义的realm中
            subject.login(token);
            log.info("login:[token:{}]", token);
//            User user = service.getOne(Wrappers.<User>lambdaQuery().eq(User::getUserName,userName).eq(User::getPassWord,passWord));

            User user = redisTemplate.opsForValue().get(SecurityUtils.getSubject().getSession().getId().toString());
//            request.getSession().setAttribute("user",user);
//            return Rs.ok(Rs.map().put("name", user.getName()).put("companyId",user.getCompanyId()), ResultCode.COMPANY_LOGIN_successful);
            return Rs.ok(Rs.map().put("name", user.getName()).put("token", SecurityUtils.getSubject().getSession().getId()), ResultCode.COMPANY_LOGIN_successful);
        } catch (UnknownAccountException e) {
            log.info("用户不存在:[{}]", userName);
            return Rs.fail(ResultCode.COMPANY_USER_NOT_EXIST);
        } catch (AuthenticationException e) {
            String msg = e.getCause().getMessage();
            if ("Unable to connect to Redis".equals(msg.substring(0, msg.indexOf(";")))) {
                log.info("redis服务没启动:{}", msg);
                return Rs.fail(ResultCode.error);
            }
            log.info("账号或密码错误:userName:[{}],passWord:[{}]", userName, passWord);
            return Rs.fail(ResultCode.COMPANY_PASSWORD_ERROR);
        } catch (AuthorizationException e) {
            log.info("没有权限:[{}]", e);
            return Rs.fail(ResultCode.NO_AUTHORITY);
        } catch (Exception e) {
            log.info("Exception异常:[{}]", e);
            return Rs.fail(ResultCode.error);
        }
    }

    /**
     * 注册用户(新建员工账号)
     * 根据不同的公司，注册该公司下的用户
     * admin角色接口
     */
    @PostMapping("/register")
    @ApiOperation(value = "注册员工", notes = "根据企业账号创建员工账号")
//    @RequiresRoles("admin")
    public ResponseEntity<Rs<Object>> register(@ApiParam("用户信息") @RequestBody @Valid UserRequest userRequest
            ,HttpServletRequest request) {
        log.info("新增员工账号接口");
        User user=PoJoUtil.transToPoJo(userRequest, User.class);
        user.setCompanyId(redisTemplate.opsForValue().get(request.getHeader("token")).getCompanyId());
        return service.register(user);
    }

    /**
     * 注册企业账号(新建公司账号)
     * 通过管理员，注册公司账号
     * superadmin角色接口
     */
    @PostMapping("/superregister")
    @ApiOperation(value = "注册企业账号", notes = "超级管理员注册企业账号")
    public ResponseEntity<Rs<Object>> superregister(@ApiParam("企业账号") @RequestBody @Valid UserCompanyRequest request) {
        log.info("创建公司账号接口");
        return service.superregister(request);
    }

}
